
package com.hlkj.pay.util;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.codec.binary.Base64;

import com.hlkj.framework.common.util.json.JsonUtils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import lombok.extern.slf4j.Slf4j;

/**
 *
 * @author HlpayTeam
 * @date 2024/10/09 13:16
 */
@Slf4j
public class SignUtilsV1 {

    /**
     * 生成 rsa 公钥 私钥
     * 
     * @return
     */
    public static String[] generateRsaKey() {
        // 生成公私钥对
        // 生成公私钥对
        KeyPair pair = SecureUtil.generateKeyPair(SignAlgorithm.SHA256withRSA.getValue());
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();
        // 获得私钥
        String privateKeyStr = bytesToBase64(privateKey.getEncoded());
        // 获得公钥
        String publicKeyStr = bytesToBase64(publicKey.getEncoded());
        String[] rsaKeys = new String[2];
        rsaKeys[0] = privateKeyStr;
        rsaKeys[1] = publicKeyStr;
        return rsaKeys;
    }

    /**
     * 己方私钥加签 合作方收到请求后，用我方公钥验签
     */
    public static String signByPriKey(Map<String, Object> params, String privateKeyStr) {
        TreeMap<String, Object> sort = MapUtil.sort(params);
        String paramsJson = JsonUtils.toJsonString(sort);
        Sign sign = new Sign(SignAlgorithm.SHA256withRSA, privateKeyStr, null);
        return Base64.encodeBase64String(sign.sign(paramsJson.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * 合作方返回结果时，会用合作方私钥加签 我们收到返回结果时，用合作方公钥验签
     */
    public static boolean checkSignByPubKey(Map<String, Object> respMap, String publicKeyStr) {
        String signValue = (String) respMap.get("sign");
        respMap.remove("sign");
        String s = JsonUtils.toJsonString(respMap);
        Sign sign = new Sign(SignAlgorithm.SHA256withRSA, null, publicKeyStr);
        return sign.verify(s.getBytes(StandardCharsets.UTF_8), Base64.decodeBase64(signValue.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * 字节数组转Base64编码
     *
     * @param bytes
     *            字节数组
     * @return Base64编码
     */
    private static String bytesToBase64(byte[] bytes) {
        byte[] encodedBytes = java.util.Base64.getEncoder().encode(bytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * Base64编码转字节数组
     *
     * @param base64Str
     *            Base64编码
     * @return 字节数组
     */
    private static byte[] base64ToBytes(String base64Str) {
        byte[] bytes = base64Str.getBytes(StandardCharsets.UTF_8);
        return java.util.Base64.getDecoder().decode(bytes);
    }
    public static void main(String[] args) {
        String[] strings = generateRsaKey();
        System.out.println(strings[0]);
        System.out.println(strings[1]);
    }
}
